package com.example.newinfinity

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.ContentValues
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.view.Gravity
import android.widget.FrameLayout.LayoutParams
import android.widget.PopupWindow
import android.widget.SeekBar
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.newinfinity.Account.AccountPopupWindow
import com.example.newinfinity.BackgroundImage.BgImageManager
import com.example.newinfinity.DownloadImage.DownloadImagePopupWindow
import com.example.newinfinity.File.FileManager
import com.example.newinfinity.IconModel.IconModelType
import com.example.newinfinity.IconModel.IconState
import com.example.newinfinity.IconModel.getDrawToolIconModels
import com.example.newinfinity.IconModel.getHomeMenuIconModels
import com.example.newinfinity.IconModel.getMenuIconModel
import com.example.newinfinity.IconModel.getOperationToolIconModels
import com.example.newinfinity.MyViewModel.DrawViewModel
import com.example.newinfinity.MyViewModel.UserViewModel
import com.example.newinfinity.View.ColorPicker.ColorPickerAdapter
import com.example.newinfinity.View.ColorPicker.getDefaultColors
import com.example.newinfinity.View.PencilPicker.PencilPickerView
import com.example.newinfinity.databinding.ColorPickerViewBinding
import com.example.newinfinity.databinding.DownLoadAnimBinding
import com.example.newinfinity.databinding.FragmentHomeBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import java.util.Date

class HomeFragment : BaseFragment<FragmentHomeBinding>() {
    private val userViewModel: UserViewModel by activityViewModels()
    //保存当前数据库中当前的登录用户
    private var currentUserName:String? = null

    override fun initViewBinding(): FragmentHomeBinding {
        return FragmentHomeBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //配置DrawViewModel
        DrawViewModel.initDrawViewModel(this)
    }

    //记录menu图标点击后动画的执行情况
    private var abcAnimType: Boolean = true
    private val aStartPlace: Int by lazy {
        mBinding.leftLayout.bottom
    }
    private val aFinallyPlace: Int by lazy {
        mBinding.leftIcons.top + 65
    }
    private val cStartPlace: Int by lazy {
        mBinding.rightLayout.left
    }
    private val cFinallyPlace: Int by lazy {
        mBinding.root.width
    }
    private val aHideAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofInt(mBinding.leftLayout, "bottom", aStartPlace, aFinallyPlace).apply {
            duration = 400
        }
    }
    private val aShowAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofInt(mBinding.leftLayout, "bottom", aFinallyPlace, aStartPlace).apply {
            duration = 400
        }
    }
    private val bHideAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofFloat(mBinding.leftMenu, "rotation", 360f, 0f).apply {
            duration = 400
        }
    }
    private val bShowAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofFloat(mBinding.leftMenu, "rotation", 0f, 360f).apply {
            duration = 400
        }
    }
    private val cHideAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofInt(mBinding.rightLayout, "left", cStartPlace, cFinallyPlace).apply {
            duration = 400
        }
    }
    private val cShowAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofInt(mBinding.rightLayout, "left", cFinallyPlace, cStartPlace).apply {
            duration = 400
        }
    }
    private val abcHideAnim: AnimatorSet by lazy {
        AnimatorSet().apply {
            this.playTogether(aHideAnim, bHideAnim, cHideAnim)
        }
    }
    private val abcShowAnim: AnimatorSet by lazy {
        AnimatorSet().apply {
            this.playTogether(aShowAnim, bShowAnim, cShowAnim)
        }
    }

    //记录arrow图标点击后动画的执行情况
    private var deAnimType: Boolean = true
    private val dStartPlace: Int by lazy {
        mBinding.topIcons.left
    }
    private val dFinallyPlace: Int by lazy {
        mBinding.topIcons.right
    }
    private val dHideAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofInt(mBinding.topIcons, "left", dStartPlace, dFinallyPlace).apply {
            duration = 400
        }
    }
    private val dShowAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofInt(mBinding.topIcons, "left", dFinallyPlace, dStartPlace).apply {
            duration = 400
        }
    }
    private val eHideAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofFloat(mBinding.arrowAnim, "rotation", 0f, 180f).apply {
            duration = 400
        }
    }
    private val eShowAnim: ObjectAnimator by lazy {
        ObjectAnimator.ofFloat(mBinding.arrowAnim, "rotation", 180f, 0f).apply {
            duration = 400
        }
    }
    private val deHideAnim: AnimatorSet by lazy {
        AnimatorSet().apply {
            this.playTogether(dHideAnim, eHideAnim)
        }
    }
    private val deShowAnim: AnimatorSet by lazy {
        AnimatorSet().apply {
            this.playTogether(dShowAnim, eShowAnim)
        }
    }

    //在该方法中可编写onCreateView时期需要编写的内容
    override fun initView() {
        super.initView()
        mBinding.leftMenu.bindIconModel(getMenuIconModel())  //绑定右上角menu的数据信息
        mBinding.leftIcons.bindIconModels(getDrawToolIconModels())  //配置左侧的icons
        mBinding.topIcons.bindIconModels(getHomeMenuIconModels())   //配置上方的icons
        mBinding.rightIcons.bindIconModels(getOperationToolIconModels()) //配置右侧的icons

        //懒加载调色盘弹窗的binding
        val colorPickerViewBinding = ColorPickerViewBinding.inflate(layoutInflater)
        //创建调色盘的弹窗视图
        val colorPickerViewPopupWindow: PopupWindow by lazy {
            PopupWindow().apply {
                this.contentView = colorPickerViewBinding.root
                this.width = LayoutParams.WRAP_CONTENT
                this.height = LayoutParams.WRAP_CONTENT
            }
        }

        //创建包裹了画笔粗细 填充类型调节弹窗视图的类
        val pencilPickerView = PencilPickerView(requireContext())
        val pencilPickerViewPopupWindow: PopupWindow by lazy {
            PopupWindow().apply {
                this.contentView = pencilPickerView
                this.width = LayoutParams.WRAP_CONTENT
                this.height = LayoutParams.WRAP_CONTENT
            }
        }

        //创建包裹了背景图片弹窗视图的类
        val bgImageManager = BgImageManager(requireContext())
        //向DrawView传递当前选中需要绘制的背景图片bitmap
        bgImageManager.bgImageChangeCallback = { bitmap ->
            mBinding.drawView.getBgBitmap(bitmap)
        }

        //用户数据库的viewModel，其内可判断当前是否有登录用户
        val userViewModel: UserViewModel by activityViewModels()

        //关于账户信息弹窗的类
        val accountPopupWindow: AccountPopupWindow by lazy {
            AccountPopupWindow(requireContext(), userViewModel)
        }

        mBinding.leftMenu.clickCallback = {  //点击menu图标的layout缩放动画
            if (!abcHideAnim.isRunning && !abcShowAnim.isRunning) {
                if (abcAnimType) {
                    abcHideAnim.start()
                } else {
                    abcShowAnim.start()
                }
                abcAnimType = !abcAnimType
                //点击每一个icon图标时 若界面中有移动move的选中图形需要将currentSelectedShape清空并修改其选中状态为MoveType.NONE
                mBinding.drawView.clearMoveShape()

                //动画发生时需要将当前已选中的icon显示取消
                //若右侧的调色盘以及画笔设置弹窗已弹出 需要hide并且将调色盘和画笔icon的显示取消
                mBinding.leftIcons.hidePopupWindowAndIconSelectedState()
                mBinding.rightIcons.hidePopupWindowAndIconSelectedState()
                colorPickerViewPopupWindow.dismiss()
                pencilPickerViewPopupWindow.dismiss()
            }
        }

        mBinding.arrowAnim.setOnClickListener {  //点击左上角的箭头图标的缩放动画
            if (!deHideAnim.isRunning && !deShowAnim.isRunning) {
                if (deAnimType) {
                    deHideAnim.start()
                } else {
                    deShowAnim.start()
                }
                deAnimType = !deAnimType

                //动画发生时需要将当前已选中的icon显示取消
                mBinding.topIcons.hidePopupWindowAndIconSelectedState()
            }
        }

        //实时获取并更新弹窗视图中的明亮度 饱和度文本数值显示
        //同时更新ColorPickerView中小圆圈的明亮度 饱和度显示
        colorPickerViewBinding.sSeekbar.setOnSeekBarChangeListener(object :
            SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                colorPickerViewBinding.sSize.text = progress.toString()
                colorPickerViewBinding.colorPickerView.changeSColor(progress.toFloat() / 100)
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {}
            override fun onStopTrackingTouch(seekBar: SeekBar?) {}
        })
        colorPickerViewBinding.vSeekbar.setOnSeekBarChangeListener(object :
            SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                colorPickerViewBinding.vSize.text = progress.toString()
                colorPickerViewBinding.colorPickerView.changeVColor(progress.toFloat() / 100)
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {}
            override fun onStopTrackingTouch(seekBar: SeekBar?) {}
        })
        //配置colorPickerView xml中recyclerView的默认色块颜色数据
        val colorPickerAdapter = ColorPickerAdapter()
        colorPickerViewBinding.colorRecyclerView.apply {
            this.adapter = colorPickerAdapter
            this.layoutManager =
                GridLayoutManager(requireContext(), 5, RecyclerView.VERTICAL, false)
        }
        val colors: MutableList<Int> = getDefaultColors()
        colorPickerAdapter.setData(colors)
        //点击调色盘中的➕➖增加删除调色盘中的色块
        colorPickerAdapter.addDeleteColorCallback = { type ->
            when (type) {
                0 -> {
                    //添加色块
                    colors.add(0, colorPickerViewBinding.colorPickerView.currentSelectedColor)
                    colorPickerAdapter.setData(colors)
                }

                1 -> {
                    //删除色块
                    colors.removeFirst()
                    colorPickerAdapter.setData(colors)
                }
            }
        }

        //显示与隐藏调色盘弹窗的方法
        fun showColorPickerView() {
            colorPickerViewPopupWindow.showAtLocation(
                mBinding.root,
                Gravity.END,
                mBinding.root.width - mBinding.rightLayout.left,
                0
            )
        }

        fun hideColorPickerView() {
            colorPickerViewPopupWindow.dismiss()
        }

        //显示与隐藏画笔弹窗的方法
        fun showPencilPickerView() {
            pencilPickerViewPopupWindow.showAtLocation(
                mBinding.root,
                Gravity.END,
                mBinding.root.width - mBinding.rightLayout.left,
                0
            )
        }

        fun hidePencilPickerView() {
            pencilPickerViewPopupWindow.dismiss()
        }

        //三方icons集合的点击callback回调给DrawView的相关处理
        mBinding.leftIcons.iconClickTypeCallback = { iconType, iconSelectState ->
            //传递给DrawView当前的绘制操作类型
            mBinding.drawView.setCurrentOperation(iconType, iconSelectState)
            //点击每一个icon图标时 若界面中有移动move的选中图形需要将currentSelectedShape清空并修改其选中状态为MoveType.NONE
            mBinding.drawView.clearMoveShape()
        }

        mBinding.rightIcons.iconClickTypeCallback = { iconType, iconSelectState ->
            when (iconType) {
                IconModelType.OPERATION_UNDO -> {
                    if (iconSelectState == IconState.SELECTED) {
                        //回退图标的选中颜色显示只需要维持200ms即可 同时将选中状态重置
                        lifecycleScope.launch(Dispatchers.Main) {
                            delay(180)
                            mBinding.rightIcons.resetSelectedState()
                        }
                        //回退
                        DrawViewModel.getDrawViewModel().layerManager.undo()
                        //DrawView中刷新视图
                        mBinding.drawView.refreshLayer()

                        hidePencilPickerView()  //选中其他icon时，画笔调节视图需要hide
                        hideColorPickerView()   //选中其他icon时，调色盘视图需要hide
                    }
                }

                IconModelType.OPERATION_DELETE -> {
                    //清空图标的选中颜色显示只需要维持200ms即可 同时将选中状态重置
                    lifecycleScope.launch(Dispatchers.IO) {
                        delay(180)
                        mBinding.rightIcons.resetSelectedState()
                    }
                    //清空
                    DrawViewModel.getDrawViewModel().layerManager.clear()
                    //DrawView中刷新视图
                    mBinding.drawView.refreshLayer()

                    hidePencilPickerView()  //选中其他icon时，画笔调节视图需要hide
                    hideColorPickerView()   //选中其他icon时，调色盘视图需要hide
                }

                IconModelType.OPERATION_PALETTE -> {
                    //调色盘视图状态切换 视图显示
                    if (iconSelectState == IconState.SELECTED) {
                        showColorPickerView()

                        hidePencilPickerView()  //选中其他icon时，画笔调节视图需要hide
                    } else {
                        hideColorPickerView()
                    }
                }

                IconModelType.OPERATION_PENCIL -> {
                    //画笔视图状态切换 视图显示
                    if (iconSelectState == IconState.SELECTED) {
                        showPencilPickerView()

                        hideColorPickerView()   //选中其他icon时，调色盘视图需要hide
                    } else {
                        hidePencilPickerView()
                    }
                }

                else -> {}
            }
        }

        mBinding.topIcons.iconClickTypeCallback = { iconType, iconSelectState ->
            when (iconType) {
                IconModelType.MENU_PICTURE -> {     //设置背景图片
                    if (iconSelectState == IconState.SELECTED) {
                        bgImageManager.showBgImagePopupWindow(mBinding.topIcons, 175, 20)
                    } else {
                        bgImageManager.hideBgImagePopupWindow()
                    }
                }

                IconModelType.MENU_DOWNLOAD -> {
                    downloadImage()
                }

                IconModelType.MENU_ACCOUNT -> {
                    if (iconSelectState == IconState.SELECTED) {
                        accountPopupWindow.show(mBinding.topIcons)
                        lifecycleScope.launch {
                            //让FileManager知道当前的登录用户
                            FileManager.instance.currentUserName = userViewModel.getCurrentLoginInUser()?.userName
                        }
                    } else {
                        accountPopupWindow.hide()
                    }
                }

                IconModelType.MENU_SAVE -> {
                    //保存当前绘制的图片到指定的文件夹中
                    //保存动画
                    anim.show(mBinding.root)

                    //获取数据库中当前登录的用户姓名
                    lifecycleScope.launch {
                        currentUserName = userViewModel.getCurrentLoginInUser()?.userName

                        mBinding.drawView.getAllBitmap().also {
                            //获取当前时间作为bitmap在文件夹路径中的名称
                            val dataName = Date()
                            //获取界面中绘制的所有内容的bitmap 并保存到对应的文件夹路径中
                            //保存完整图片
                            FileManager.instance.saveBitmapInPath(it, "$dataName", true,currentUserName)
                            //保存缩略压缩的图片
                            val scaleBitmap = Bitmap.createScaledBitmap(it, (it.width * 0.3).toInt(), (it.height * 0.3).toInt(), true)
                            FileManager.instance.saveBitmapInPath(scaleBitmap, "$dataName", false,currentUserName)
                        }
                        //隐藏动画
                        anim.hide()

                        //保存图片选中状态只需要维持180ms即可 同时将选中状态重置
                        delay(200)
                        mBinding.topIcons.resetSelectedState()
                    }
                }

                else -> {}
            }
        }

    }

    //下载动画弹窗
    private val anim: DownloadImagePopupWindow by lazy {
        DownloadImagePopupWindow(requireContext())
    }

    //下载图片到本地
    private fun downloadImage() {
        //下载动画
        anim.show(mBinding.root)

        lifecycleScope.launch(Dispatchers.IO) {
            //延时1s让动画消失
            delay(1000)
            anim.hide()
        }

        //下载图片选中状态只需要维持200ms即可 同时将选中状态重置
        lifecycleScope.launch(Dispatchers.Main) {
            delay(180)
            mBinding.topIcons.resetSelectedState()
        }

        //进行下载到本地相册操作
        //获取当前的所有bitmap集合
        val bitmap = mBinding.drawView.getAllBitmap()
        //定位图片在系统中的位置
        val imagesUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
        } else {
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        }
        //确定插入的数据和对应的字段
        val contentValues = ContentValues().apply {
            //当前的系统日期和时间（精确到毫秒）
            // 输出类似：Mon Oct 30 14:45:30 GMT+08:00 2023
            val date = Date()
            //确定名字 注意唯一
            put(MediaStore.Images.Media.DISPLAY_NAME, "$date")
            put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        }
        //获取即将插入的图片在系统相册里面最准确的内容地址uri
        val imgUri = requireContext().contentResolver.insert(imagesUri, contentValues)
        imgUri?.let {
            //获取对应输出流
            requireContext().contentResolver.openOutputStream(imgUri)?.use {
                //将bitmap通过这个输出流写入imgUri指定的位置
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
            }
        }
    }
}